package com.example.custsecurity.security.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class CustJwtService {

  @Value("${token.exp.day}")
  private String tokenExp;


  public String obtainToken(Authentication authentication){

    //   获取已认证的账号
    String username = ((User)authentication.getPrincipal()).getUsername();

//    获取已授权的权限
    List<GrantedAuthority> list = (List<GrantedAuthority>)authentication.getAuthorities();
    String authority_string = "";
//    将权限列表转成字符串保存到 jwt token 中
    for(int i=0; i<list.size();i++){
      if(i == list.size()-1){
        authority_string+= list.get(i).getAuthority();
      }else{
        authority_string+= list.get(i).getAuthority()+",";
      }
    }

    Calendar expDate = Calendar.getInstance();
//    expDate.add(Calendar.DATE ,Integer.parseInt(tokenExp));
    expDate.add(Calendar.SECOND ,5);

//   查询数据库 获取客户的账号  account solt

    return JWT.create()
      .withExpiresAt(expDate.getTime()) //设置过期时间
      .withIssuedAt(new Date()) //设置token的发放时间
      .withClaim("account", username) //自定义的数据 存放对应用户的账号
      .withClaim("role", authority_string) //自定义的数据 存放对应用户的角色
      .sign(Algorithm.HMAC256("newer")); //JWT 签名的设置 选择加密HMAC256方式 秘钥 值为 字符串newer

  }

 public String createJWTToken(){

   Calendar expDate = Calendar.getInstance();
   expDate.add(Calendar.SECOND,3);

//   查询数据库 获取客户的账号  account solt

   return JWT.create()
                     .withExpiresAt(expDate.getTime()) //设置过期时间
                     .withAudience("0007") //设置token 接受者
                     .withIssuedAt(new Date()) //设置token的发放时间
                     .withClaim("account", "张三") //自定义的数据 存放对应用户的账号
                     .withClaim("role", "ADMIN") //自定义的数据 存放对应用户的角色
                     .withClaim("dept", "技术部") //自定义的数据 存放对应用户的所属部门
                     .sign(Algorithm.HMAC256("newer")); //JWT 签名的设置 选择加密HMAC256方式 秘钥 值为 字符串newer

 }

 public Map<String, Object> decodeWTToken(String token){

   Map<String, Claim> jwtMap = JWT.decode(token).getClaims();
   log.debug("........获取token:{}", jwtMap);


   Claim exp = JWT.decode(token).getClaim("exp");
   Claim iat = JWT.decode(token).getClaim("iat");
   Claim aud = JWT.decode(token).getClaim("account");
   Claim role = JWT.decode(token).getClaim("role");

   Map<String, Object> map = new HashMap<>();
   map.put("exp", exp.asDate());
   map.put("iat", iat.asDate());
   map.put("account", aud.asString());
   map.put("role", role.asString());

   return map;

 }

  public Map<String, Object> verifyJWTToken(String token){

    Map<String, Object> map = new HashMap<>();

      JWTVerifier verifier = JWT.require(Algorithm.HMAC256("newer")).build();
      DecodedJWT decodeJWT =   verifier.verify(token);
    Claim exp = decodeJWT.getClaim("exp");
    Claim iat = decodeJWT.getClaim("iat");
    Claim aud = decodeJWT.getClaim("account");
    Claim role = decodeJWT.getClaim("role");

    map.put("exp", exp.asDate());
    map.put("iat", iat.asDate());
    map.put("account", aud.asString());
    map.put("role", role.asString());
    return map;
  }

 /*public Map<String, Object> verifyJWTToken(String token){

   Map<String, Object> map = new HashMap<>();
   try{
     JWTVerifier verifier = JWT.require(Algorithm.HMAC256("newer")).build();
     DecodedJWT decodeJWT =   verifier.verify(token);
   }catch(Exception e){
//      throw new RuntimeException(e.getMessage());
     map.put("code", 500);
     map.put("err", e.getMessage());
     return map;
   }

  map.put("code", 200);
   return map;
 }*/


}
